const common = require("../utils/common")
const fishConfig = require("../data/fish.json")
const fishPool = Object.keys(fishConfig).map(key => fishConfig[key])

class Player {
  id = 0
  connectionId = ''
  roomId = 0
  name = ''
  position = 1
  props = {
    angle: 0,
    goldEx: 1000000,
    paoshu: 1000,
    bullet: 0,
  }
  constructor(id, roomId) {
    this.id = id
    this.roomId = roomId
    this.name = roomId
  }
  update (props) {
    Object.assign(this.props, props)
  }
}
class Room {
  id = ''
  state = 0 // 状态 0=空闲，1=满座
  player = []
  fish = []
  MaxPlayer = 4
  MaxFish = 50
  view = { width: 0, height: 0 }
  constructor(id, option) {
    this.id = id
    this.view = option.view
    this.addFish(this.MaxFish)
  }
  addPlayer (player) {
    if (this.player.length === 4) return
    player.position = this.player.length + 1
    this.player.push(player)
    if (this.player.length === 4) this.state = 1
  }
  removePlayer (playerId) {
    const index = this.player.findIndex(player => player.id == playerId)
    if (index == -1) return
    this.player.splice(index, 1)
    this.state = 0
  }
  initFish () {
    const fish = JSON.parse(JSON.stringify(fishPool[common.rndInt(0, 17)]))

    let x, angle, scaleY = 1
    if (Math.random() < 0.5) {
      x = 0
      angle = common.rnd(0, 30)
    } else {
      x = this.view.width
      angle = common.rnd(-200, -170)
      scaleY = -1
    }
    fish.position = { x, y: common.rnd(0, this.view.height), z: 0 }
    fish.scale = { x: 1, y: scaleY, z: 0 }
    fish.angle = angle
    fish.type = 1
    fish.order = common.GenerateId.getFishId()
    return fish
  }
  addFish (count) {
    for (let i = 0; i < count; i++) {
      let fish = this.initFish()

      this.fish.push(fish)
    }
  }
  updateFish (ids) {
    for (let i = this.fish.length - 1; i >= 0; i--) {
      this.fish[i].type = 0
      if (ids.includes(this.fish[i].id)) {
        this.fish.splice(i, 1)
      }
    }
    this.addFish(this.MaxFish - this.fish.length)
  }
  update (props, playerId) {
    this.player.find(player => player.id == playerId)?.update(props.player[playerId].props)
    this.updateFish(Object.keys(props.fish))
  }
  getData () {
    return JSON.parse(JSON.stringify({
      id: this.id,
      fish: JSON.parse(JSON.stringify(this.fish)),
      player: JSON.parse(JSON.stringify(this.player))
    }))
  }
}

// 房间列表
const RoomList = []
const PlayerMap = new Map()

module.exports.FrameSyncExecutor = class {
  /**
   * 一个逻辑帧的处理，正常由内部定时器调用，只有在单元测试时可以让外部调用进行测试
   */
  onSyncOneFrameHandler (io) {
    try {
      RoomList.forEach(room => {
        io.to(room.id).emit('update', JSON.stringify(room.getData()))
      })
    } catch (e) {
      console.log(e);
    }
  }
  /**
   * 同步游戏状态数据
   * @param stateData
   * @param stateFrameIndex
   */
  syncStateData (stateData, io) {
    try {
      RoomList.find(item => item.id == PlayerMap.get(io.id))?.update(JSON.parse(stateData), io.id)
    } catch (e) {
      console.log(e);
    }
  }

  /**
   * 添加连接的输入操作到下一帧
   * @param io
   * @param option
   */
  addConnectionInpFrame (io, option, socket) {
    try {
      option = option ? JSON.parse(option) : {}
    } catch (e) {
      option = {}
    }

    const idleRoom = RoomList.find(room => room.state == 0)
    if (idleRoom) {
      io.join(idleRoom.id)
      idleRoom.addPlayer(new Player(io.id, idleRoom.id))
      PlayerMap.set(io.id, idleRoom.id)
      socket.to(io.id).emit('init', JSON.stringify({
        playerId: io.id,
        ...idleRoom.getData()
      }))
      return
    }
    const roomId = common.GenerateId.getRoomId()
    io.join(roomId)
    const room = new Room(roomId, option)
    room.addPlayer(new Player(io.id, roomId))
    PlayerMap.set(io.id, roomId)
    RoomList.push(room)
    socket.to(io.id).emit('init', JSON.stringify({
      playerId: io.id,
      ...room.getData()
    }))
  }
  // 离开房间
  leaveConnectionInpFrame (io) {
    // const idleRoom = RoomList.find(room => room.state == 0)
  }

  /**获取给连接发追帧数据(最后状态数据+追帧包) */
  buildAfterFramesMsg () {
  }
}